﻿using Business;
using SH3H.CSM.Common.LogUtil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using ThreadsTest.Models;

namespace ThreadsTest.Controllers
{
    [RoutePrefix("api/Threads")]
    public class ThreadsController : ApiController
    {
        /// <summary>
        /// ThreadPoolTest 仅限64条处理
        /// </summary>
        /// <param name="counts"></param>
        /// <returns></returns>
        [Route("Test")]
        [HttpGet]
        public bool Test([FromUri]int counts) {
            LogUtil.Info("Multi-Start");
            ThreadPool.SetMaxThreads(8, 8);
            ManualResetEvent[] _ManualEvents = new ManualResetEvent[counts];
            for (int i = 0; i < counts; i++)
            {
                _ManualEvents[i] = new ManualResetEvent(false);
                ThreadModel m = new ThreadModel();
                m.count = i + 1;
                m.tEvent = _ManualEvents[i];
                ThreadPool.QueueUserWorkItem(Deal, m);
            }
            ManualResetEvent.WaitAll(_ManualEvents);

            //CountDownLatch cdl = new CountDownLatch(counts);
            //for (int i = 0; i < counts; i++)
            //{
            //    ThreadPool.QueueUserWorkItem(new WaitCallback(Tasks[i]), cdl);
            //}
            //cdl.Await();
            LogUtil.Info("Multi-End");
            return true;
        }

        private void Deal(object state)
        {
            ThreadModel m = (ThreadModel)state;
            LogUtil.Info("Multi-Porcess-"+m.count.ToString());
            DateTime now = DateTime.Now;
            DateTime time = DateTime.Now;
            while (time.AddSeconds(2) > now)
            {
                now = DateTime.Now;
            }
            m.tEvent.Set();
        }
        /// <summary>
        /// 单线程
        /// </summary>
        /// <param name="counts"></param>
        /// <returns></returns>
        [Route("TestOne")]
        [HttpGet]
        public bool TestOne([FromUri]int counts)
        {
            LogUtil.Info("One-Start");
            for (int i = 0; i < counts; i++) {
                Deal(i+1);
            }
            LogUtil.Info("One-End");
            return true;
        }


        static void Deal(int i) {
            LogUtil.Info("One-Porcess-" + i.ToString());
            DateTime now = DateTime.Now;
            DateTime time = DateTime.Now;
            while (time.AddSeconds(3) > now) {
                now = DateTime.Now;
            }
            //return true;
        }

        /// <summary>
        /// 多线程方法1
        /// </summary>
        /// <param name="counts"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        [Route("TestTask")]
        [HttpGet]
        public async Task<bool> TestTask([FromUri]int counts, [FromUri] int userId)
        {
            LogUtil.Info("Task-Start-" + userId);
            List<int> l = new List<int>();
            List<Task> tasks = new List<Task>();
            for (var i = 0; i < counts; i++)
            {
                int t = i;
                Task task = Task.Factory.StartNew(() =>
                {

                    var d=new OperateBusiness().DealTask(t);
                    lock (l)
                    {
                        l.Add(d);
                    }
                });
                tasks.Add(task);
            }
            await Task.WhenAll(tasks);
            LogUtil.Info("Task-End-" + userId);
            return true;
        }

        /// <summary>
        /// 多线程方法2
        /// </summary>
        /// <param name="counts"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        [Route("TestTask2")]
        [HttpGet]
        public bool TestTask2([FromUri]int counts,[FromUri] int userId)
        {
            LogUtil.Info("Task2-Start-" + userId);
            List<int> l = new List<int>();
            //List<Task> tasks = new List<Task>();
            CountdownEvent _count = new CountdownEvent(counts);
            for (var i = 0; i < counts; i++)
            {
                int t = i;
                Task.Factory.StartNew(() =>
                {
                    new OperateBusiness().DealTask(t,_count,ref l);

                });
            }
            _count.Wait();
            LogUtil.Info("Task2-End-"+ userId);
            return true;
        }

        /// <summary>
        /// 多线程方法2
        /// </summary>
        /// <param name="counts"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        [Route("TestTaskWithAccess")]
        [HttpGet]
        public bool TestTaskWithAccess([FromUri]int counts, [FromUri] int userId)
        {
            LogUtil.Info("TaskWithAccess-Start-" + userId);
            List<int> l = new List<int>();
            //List<Task> tasks = new List<Task>();
            CountdownEvent _count = new CountdownEvent(counts);
            for (var i = 1; i < counts+1; i++)
            {
                int t = i;
                Task.Factory.StartNew(() =>
                {
                    new OperateBusiness().DealTaskWithDataAccess(t, _count, ref l);

                });
            }
            _count.Wait();
            LogUtil.Info("TaskWithAccess-End-" + userId + "|||" + Newtonsoft.Json.JsonConvert.SerializeObject(l.OrderBy(m => m)));
            return true;
        }

        /// <summary>
        /// 事务测试
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Route("TestTran")]
        [HttpGet]
        public int TestTran([FromUri] int id) {
            return new OperateBusiness().TestTrans(id);
        }

        /// <summary>
        /// 事务测试
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Route("TestTranNew")]
        [HttpGet]
        public bool TestTranNew()
        {
            return new OperateBusiness().TestTranNew();
        }

        /// <summary>
        /// 事务测试(多线程)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Route("TestTranMulti")]
        [HttpGet]
        public int TestTranMulti([FromUri] string ids)
        {
            List<int> l = new List<int>();
            var idsArr = ids.Split(',');
            CountdownEvent _count = new CountdownEvent(idsArr.Count());
            foreach (var item in idsArr) {
                int i = Convert.ToInt32(item);
                Task.Factory.StartNew(() =>
                {
                    var res = new OperateBusiness().TestTran(i,_count);
                    lock (l) {
                        l.Add(res);
                    }
                });
            }
            _count.Wait();
            return l.Count;
        }

        [Route("AddCache")]
        [HttpGet]
        public void Cache() {
            OperateBusiness b = new OperateBusiness();
            b.AddCache();
            b.GetCache();
        }


        [Route("TestMysql")]
        [HttpGet]

        public string GetMySqlData()
        {
            OperateBusiness b = new OperateBusiness();
            return b.GetMySqlData();
        }
    }

}
